﻿Imports Microsoft.VisualStudio.TestTools.UnitTesting

Imports VBF.CompilerModel.Scanner
Imports System.Runtime.Serialization
Imports System.IO



'''<summary>
'''This is a test class for CharIndexTableTest and is intended
'''to contain all CharIndexTableTest Unit Tests
'''</summary>
<TestClass()> _
Public Class CharIndexTableTest


    Private testContextInstance As TestContext

    '''<summary>
    '''Gets or sets the test context which provides
    '''information about and functionality for the current test run.
    '''</summary>
    Public Property TestContext() As TestContext
        Get
            Return testContextInstance
        End Get
        Set(ByVal value As TestContext)
            testContextInstance = value
        End Set
    End Property

#Region "Additional test attributes"
    '
    'You can use the following additional attributes as you write your tests:
    '
    'Use ClassInitialize to run code before running the first test in the class
    '<ClassInitialize()>  _
    'Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)
    'End Sub
    '
    'Use ClassCleanup to run code after all tests in a class have run
    '<ClassCleanup()>  _
    'Public Shared Sub MyClassCleanup()
    'End Sub
    '
    'Use TestInitialize to run code before running each test
    '<TestInitialize()>  _
    'Public Sub MyTestInitialize()
    'End Sub
    '
    'Use TestCleanup to run code after each test has run
    '<TestCleanup()>  _
    'Public Sub MyTestCleanup()
    'End Sub
    '
#End Region


    <TestMethod()> _
    Public Sub MatchTest_Simple()
        Dim table As New CharIndexTable(Of String)

        For i = AscW("z"c) To AscW("a"c) Step -1
            Dim c = ChrW(i)
            table.Add(c, c.ToString)

        Next

        For i = AscW("a"c) To AscW("z"c)
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(c.ToString, s)
        Next
    End Sub

    <TestMethod()> _
    Public Sub MatchTest_SimpleUnicode()
        Dim table As New CharIndexTable(Of String)

        For i = AscW("９"c) To AscW("１"c) Step -1
            Dim c = ChrW(i)
            table.Add(c, c.ToString)

        Next

        For i = AscW("１"c) To AscW("９"c)
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(c.ToString, s)
        Next
    End Sub

    <TestMethod()> _
    Public Sub MatchTest_SimpleWithRange()
        Dim table As New CharIndexTable(Of String)

        For i = AscW("z"c) To AscW("f"c) Step -1
            Dim c = ChrW(i)
            table.Add(c, c.ToString)
        Next

        Dim range1 = "Range1 a-e"
        Dim range2 = "Range2 1-9"
        Dim range3 = "Range3 B-Y"

        table.Add(New CharRange("a"c, "e"c), range1)
        table.Add(New CharRange("1"c, "9"c), range2)
        table.Add(New CharRange("B"c, "Y"c), range3)

        For i = AscW("f"c) To AscW("z"c)
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(c.ToString, s)
        Next

        For i = AscW("a"c) To AscW("e"c)
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(range1, s, "Testing " & c.ToString)
        Next

        For i = AscW("1"c) To AscW("9"c)
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(range2, s, "Testing " & c.ToString)
        Next

        For i = AscW("Y"c) To AscW("B"c) Step -1
            Dim c = ChrW(i)
            Dim s = table.Match(c)

            Assert.AreEqual(range3, s, "Testing " & c.ToString)
        Next

        Assert.AreEqual(Nothing, table.Match("0"c))
        Assert.AreEqual(Nothing, table.Match(" "c))
        Assert.AreEqual(Nothing, table.Match("A"c))
        Assert.AreEqual(Nothing, table.Match("Z"c))

    End Sub

    <TestMethod()>
    Public Sub MatchTest_RangeAsChar()
        Dim table As New CharIndexTable(Of String)

        Dim range1 = "Range1 c-e"
        table.Add(New CharRange("c"c, "e"c), range1)

        table.Add(New CharRange("f"c, "f"c), "f")

        table.Add("g"c, "g")

        Assert.AreEqual(Nothing, table.Match("b"c))
        Assert.AreEqual(range1, table.Match("c"c))
        Assert.AreEqual(range1, table.Match("d"c))
        Assert.AreEqual(range1, table.Match("e"c))
        Assert.AreEqual("f", table.Match("f"c))
        Assert.AreEqual("g", table.Match("g"c))
        Assert.AreEqual(Nothing, table.Match("h"c))
    End Sub

    <TestMethod()>
    Public Sub MatchTest_MixedRange()
        Dim table As New CharIndexTable(Of String)

        Dim range1 = "Range1"
        table.Add(New CharRange("b"c, "啊"c), range1)



        Assert.AreEqual(Nothing, table.Match("a"c))
        Assert.AreEqual(range1, table.Match("b"c))
        Assert.AreEqual(range1, table.Match("f"c))
        Assert.AreEqual(range1, table.Match("z"c))
        Assert.AreEqual(range1, table.Match("啊"c))
        Assert.AreEqual(Nothing, table.Match("囧"c))
    End Sub

    <TestMethod()>
    Public Sub AddTest_CharDuplicate()
        Dim table As New CharIndexTable(Of String)

        table.Add("A"c, "A")
        table.Add("A"c, "Error")

        Assert.AreEqual("A", table.Match("A"c))

    End Sub

    <TestMethod()>
    Public Sub AddTest_CharDuplicateUnicode()
        Dim table As New CharIndexTable(Of String)

        table.Add("啊"c, "啊")
        table.Add("啊"c, "Error")

        Assert.AreEqual("啊", table.Match("啊"c))

    End Sub

    <TestMethod()>
    Public Sub AddTest_CharRangeConflict()
        Dim table As New CharIndexTable(Of String)
        table.Add("A"c, "A")
        table.Add(New CharRange("A"c, "F"c), "A-F")
        table.Add("C"c, "C")


        Assert.AreEqual("A", table.Match("A"c))
        Assert.AreEqual("A-F", table.Match("B"c))
        Assert.AreEqual("A-F", table.Match("C"c))
        Assert.AreEqual("A-F", table.Match("F"c))
    End Sub

    <TestMethod()>
    Public Sub AddTest_CharRangeConflictUnicode()
        Dim table As New CharIndexTable(Of String)
        table.Add("５"c, "５")
        table.Add(New CharRange("１"c, "６"c), "１-６")
        table.Add("２"c, "２")


        Assert.AreEqual("５", table.Match("５"c))
        Assert.AreEqual("１-６", table.Match("２"c))
        Assert.AreEqual("１-６", table.Match("３"c))
        Assert.AreEqual("１-６", table.Match("６"c))
    End Sub


    <TestMethod()>
    Public Sub AddTest_RangeRangeConflict()
        Dim table As New CharIndexTable(Of String)
        table.Add(New CharRange("E"c, "G"c), "E-G")

        table.Add(New CharRange("A"c, "E"c), "A-E")
        table.Add(New CharRange("E"c, "F"c), "E-F")
        table.Add(New CharRange("F"c, "I"c), "F-I")

        Assert.AreEqual("E-G", table.Match("F"c))
        Assert.AreEqual("A-E", table.Match("A"c))
        Assert.AreEqual("F-I", table.Match("H"c))

    End Sub

    <TestMethod()>
    Public Sub AddTest_RangeRangeConflictUnicode()
        Dim table As New CharIndexTable(Of String)
        table.Add(New CharRange("５"c, "７"c), "５-７")

        table.Add(New CharRange("１"c, "４"c), "１-４")
        table.Add(New CharRange("５"c, "６"c), "５-６")
        table.Add(New CharRange("７"c, "９"c), "７-９")

        Assert.AreEqual("５-７", table.Match("６"c))
        Assert.AreEqual("１-４", table.Match("１"c))
        Assert.AreEqual("７-９", table.Match("８"c))

    End Sub

    <TestMethod()>
    Public Sub CharIndexTable_SerialzationTest()
        Dim table As New CharIndexTable(Of String)
        table.Add("A"c, "A")
        table.Add(New CharRange("A"c, "F"c), "A-F")
        table.Add("５"c, "５")
        table.Add(New CharRange("１"c, "６"c), "１-６")

        Dim serializer As New DataContractSerializer(table.GetType())

        Dim stream As New MemoryStream

        serializer.WriteObject(stream, table)

        stream.Seek(0, SeekOrigin.Begin)

        Dim sr As New StreamReader(stream)
        Dim serializedString = sr.ReadToEnd

        stream.Seek(0, SeekOrigin.Begin)

        Dim table2 = TryCast(serializer.ReadObject(stream), CharIndexTable(Of String))

        Assert.AreEqual("A", table2.Match("A"c))
        Assert.AreEqual("A-F", table2.Match("B"c))
        Assert.AreEqual("A-F", table2.Match("C"c))
        Assert.AreEqual("A-F", table2.Match("F"c))
        Assert.AreEqual("５", table2.Match("５"c))
        Assert.AreEqual("１-６", table2.Match("２"c))
        Assert.AreEqual("１-６", table2.Match("３"c))
        Assert.AreEqual("１-６", table2.Match("６"c))
    End Sub
End Class
